/*
 * A "MasterMind" type game.
 *
 * Copyright 1995-2003 Dave Dunfield
 * All rights reserved.
 *
 * Permission granted for personal (non-commercial) use only.
 *
 * Compile command: cc mmind -fop
 */
#include <stdio.h>

#define	DIGITS	10

extern unsigned RAND_SEED;

unsigned char pegs[DIGITS], buffer[50], num_pegs;

char use[] = { "\n\
Given a set of 'n' digits (0-9), you must guess which digits are in\n\
the set and in which order.\n\n\
For each guess, the computer will display one \002 for each digit of your\n\
guess which is in the correct position, and one \001 for each digit which\n\
is in the set but is NOT in the correct position.\n\n\
To start the game type 'MMIND n' where 'n' is the number of digits (2-10).\n\
For a more challenging game, type 'MMIND n DUP', which lets the computer\n\
choose duplicate digits within the set.\n\n" };

/*
 * Main program
 */
main(int argc, char *argv[])
{
	unsigned i, j, k;
	static unsigned try_count = 0;
	static char dup = 0;

	if(argc < 2)
		abort(use);

	/* Get number of pegs in game */
	num_pegs = atoi(argv[1]);
	if((num_pegs < 2) || (num_pegs > DIGITS))
		abort("Please use a number between 2 and 10");

	if((argc > 2) && (toupper(*argv[2]) == 'D'))
		dup = -1;

	get_time(&i, &j, &k);
	RAND_SEED = (j*60) + k;

	/* Select digit set for this game */
	for(i=0; i < DIGITS; ++i)
		pegs[i] = dup ? random(DIGITS) : i;

	/* Shuffle digit set to create playing set */
	for(i=0; i < DIGITS; ++i) {
		k = pegs[j = random(DIGITS)];
		pegs[j] = pegs[i];
		pegs[i] = k; }

	for(;;) {
		++try_count;
		do {
			printf("Enter your guess (%u digits)?", num_pegs);
			fgets(buffer, sizeof(buffer)-1, stdin);
			if(!*buffer)
				return;
			for(i=0; buffer[i]; ++i)
				if(!isdigit(buffer[i]))
					break; }
		while(i != num_pegs);

		printf("[");

		/* Count pegs in correct position */
		for(i=k=0; i < num_pegs; ++i)
			if(((pegs[i] &= 0x7F)+'0') == buffer[i]) {
				pegs[i] |= 0x80;
				buffer[i] = -1;
				++k;
				putc(0x02, stdout); }

		/* If he has them all - He WINS! */
		if(k >= num_pegs)
			break;

		/* Count pegs NOT in correct position */
		for(i=0; i < num_pegs; ++i)
			for(j=0; j < num_pegs; ++j)
				if((pegs[i]+'0') == buffer[j]) {
					buffer[j] = -1;
					putc(0x01, stdout);
					++k;
					break; }

		/* Padd output to correct number of pegs */
		while(k++ < num_pegs)
			putc(' ', stdout);

		printf("]\n"); }

	printf("]\nYou guessed it in %d tries!\n", try_count);
}
